package cn.boltzjf.sql4j.dao;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.boltzjf.sql4j.Column;
import cn.boltzjf.sql4j.ResultConverter;
import cn.boltzjf.sql4j.Row;

public class RowResultConverter implements ResultConverter<Row> {

    private final Map<String, Column<?>> nameToColMap = new HashMap<>();
    private final ValueConverter valueConverter;

    public RowResultConverter(ValueConverter valueConverter, Column<?>... columns) {
        this.valueConverter = valueConverter != null ? valueConverter : ValueConverter.DEFAULT_INSTANCE;
        if (columns != null && columns.length > 0) {
            for (Column<?> column : columns) {
                nameToColMap.put(column.name(), column);
            }
        }
    }
    
    public RowResultConverter(Column<?>... columns) {
        this(null, columns);
    }

    @Override
    public List<Row> convert(ResultSet rs) throws SQLException {
        ResultSetMetaData meta = rs.getMetaData();
        Column<?>[] rsColumns = new Column<?>[meta.getColumnCount()];
        for (int i = 0; i < rsColumns.length; ++i) {
            rsColumns[i] = nameToColMap.get(meta.getColumnLabel(i + 1));
        }

        List<Row> rows = new ArrayList<>();
        while (rs.next()) {
            Row row = new Row();
            for (int i = 0; i < rsColumns.length; ++i) {
                Object o = rs.getObject(i + 1);
                Column<?> col = rsColumns[i];
                if (col != null) {
                    row.put(col, valueConverter.fromDb(o, col.type()));
                }
            }
            rows.add(row);
        }
        return rows;
    }

}
